package com.org.oracle.service.impl;

import cn.hutool.core.io.FileUtil;
import com.alibaba.excel.EasyExcel;
import com.org.oracle.mysql.entity.QuestionChapters;
import com.org.oracle.mysql.entity.Questions;
import com.org.oracle.service.FileService;
import com.org.oracle.service.QuestionChaptersService;
import com.org.oracle.service.SubjectsService;
import com.org.oracle.strategy.FileStrategy;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.*;

/**
 * @author: heiye
 * @date: 2024/12/10 下午12:47
 * @version: v1.0.0
 * @description:
 */
@Service
public class FileServiceImpl implements FileService {

    @Resource
    private FileStrategy fileStrategy;

    @Resource
    private SubjectsService subjectsService;

    @Resource
    private QuestionChaptersService chaptersService;

    private static final String BUCKET_NAME = "heiye-test";

    /**
     * 上传图片
     *
     * @param image
     * @return
     */
    @Override
    public String uploadImg(MultipartFile image) {
        return fileStrategy.uploadImg(image, BUCKET_NAME);
    }

    /**
     * 解析CSV文件
     * @param tempFilePath 以uuid命名的临时文件
     * @return 完整的question对象
     */
    @Override
    public List<Questions> parseCsv(String tempFilePath) {
        List<String> lines = FileUtil.readLines(new File(tempFilePath),"UTF-8");
        List<Questions> questions = new ArrayList<>();
        for (String line : lines) {
            // 校验每行的列数是否正确

            String[] parts = line.split("/");
            if (parts.length != 8) {
                throw new IllegalArgumentException("CSV 文件格式不正确，应该有 8 列数据。");
            }
            Questions question = new Questions();
            // 传入的是科目名称，需要转化为科目id
            String subjectName = parts[0];
            String subjectId = subjectsService.getSubjectIdByName(subjectName);
            question.setSubjectId(subjectId);
            // 传入的是章节名称，需要转化为章节id
            String chapterName = parts[1];
            String chapterId = chaptersService.getChapterIdByName(chapterName);
            question.setChapterId(chapterId);
            question.setType(parts[2]);
            question.setContent(parts[3]);
            question.setExplanation(parts[4]);
            question.setAnswer(parts[5]);
            question.setOptions(parts[6]); // CSV 格式中的选项可以是一个 JSON 字符串
            question.setDifficulty(Integer.parseInt(parts[7]));
            questions.add(question);
        }
        return questions;
    }

    /**
     * easyExcel同步读取并处理问题
     * @param tempFilePath 文件以字符串类型传入
     * @return 处理好的问题集合
     */
    @Override
    public List<Questions> parseExcel(String tempFilePath) {
        // 读取 Excel 文件，指定第一行作为表头
        List<Map<Integer, String>> data = EasyExcel.read(tempFilePath)
                .sheet(0)
                .headRowNumber(0)  // 表头在第一行
                .doReadSync();
//        // 打印第一行的表头，确保数据正确
//        System.out.println("第一行数据：" + data.get(0));  // 打印第一行的内容
        // 获取表头（第一行）
        Map<Integer, String> headerRow = data.get(0);
        Map<String, Integer> headerMap = new HashMap<>();
        //校验表头是否包含重复项
        Set<String> headerNames = new HashSet<>();
        for (Map.Entry<Integer, String> entry : headerRow.entrySet()) {
            String columnName = entry.getValue();
            if(headerNames.contains(columnName)){
                throw new RuntimeException("Excel 文件表头中列名 '" + columnName + "' 存在重复，请检查表头数据。");
            }
            headerNames.add(columnName);
            headerMap.put(entry.getValue(), entry.getKey());  // 将表头内容映射为键值对
        }
        // 检查表头是否包含必要的字段
        if (!headerMap.containsKey("科目") ||!headerMap.containsKey("章节") || !headerMap.containsKey("题目类型")
                || !headerMap.containsKey("题目内容") || !headerMap.containsKey("解析") || !headerMap.containsKey("答案")
                || !headerMap.containsKey("选项") || !headerMap.containsKey("难度")) {
            throw new RuntimeException("Excel 文件表头格式不正确，必须包含: 科目, 章节, 题目类型, 题目内容, 解析, 答案, 选项, 难度");
        }

        // 解析剩余数据（从第二行开始）
        List<Questions> questions = new ArrayList<>();
        for (int i = 1; i < data.size(); i++) {
            // 获取当前行数据
            Map<Integer, String> row = data.get(i);
            Questions question = new Questions();
            //获取并设置科目名称
            String subjectName = row.get(headerMap.get("科目"));
            // 传入的是科目名称，需要转化为科目id
            String subjectId = subjectsService.getSubjectIdByName(subjectName);
            question.setSubjectId(subjectId);
            // 获取并设置章节名称
            String chapterName = row.get(headerMap.get("章节"));
            // 传入的是章节名称，需要转化为章节id
            String chapterId = chaptersService.getChapterIdByName(chapterName);
            question.setChapterId(chapterId);
            // 设置题目类型、内容、答案、选项和难度
            question.setType(row.get(headerMap.get("题目类型")));
            question.setContent(row.get(headerMap.get("题目内容")));
            //处理解析
            question.setExplanation(row.get(headerMap.get("解析")));
            //处理答案
            question.setAnswer(row.get(headerMap.get("答案")));
            // 处理选项
            String options = row.get(headerMap.get("选项"));
            if (options != null && !options.isEmpty()) {
                question.setOptions(options);  // 假设选项列是有效的 JSON 字符串
            } else {
                question.setOptions("{}");  // 如果没有选项，设置一个默认值
            }
            // 设置难度
            try {
                question.setDifficulty(Integer.parseInt(row.get(headerMap.get("难度"))));
            } catch (NumberFormatException e) {
                throw new RuntimeException("难度字段不是有效的整数，第 " + (i + 1) + " 行数据无法解析");
            }
            questions.add(question);
        }
        return questions;
    }
}
